/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package com.plian.system.service.pf.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.common.status.CustomCode;
import com.plian.system.constant.baseinfo.ValueSetConstant;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.dto.pf.BaseWelfareExpendDTO;
import com.plian.system.entity.pf.BaseWelfareExpend;
import com.plian.system.entity.pf.WelfareExpend;
import com.plian.system.entity.pm.propertyinformation.PropertyTime;
import com.plian.system.mapper.pf.BaseWelfareExpendMapper;
import com.plian.system.mapper.pf.WelfareExpendMapper;
import com.plian.system.mapper.pf.WelfareSummaryRelationMapper;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.ObjResult;
import com.plian.system.model.R;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.mybatis.base.BaseServiceImpl;
import com.plian.system.mybatis.search.SearchEntity;
import com.plian.system.mybatis.search.SearchParamEntiy;
import com.plian.system.mybatis.support.Condition;
import com.plian.system.mybatis.support.Query;
import com.plian.system.service.bt.baseinfo.BaseInfoService;
import com.plian.system.service.pf.IBaseWelfareExpendService;
import com.plian.system.service.pf.IWelfareExpendService;
import com.plian.system.service.pf.IWelfareSummaryRelationService;
import com.plian.system.service.sys.code.IFormCodeService;
import com.plian.system.service.sys.orgzation.OrgzationService;
import com.plian.system.service.wf.FormWorkflowService;
import com.plian.system.service.wfTwo.WorkflowTwoService;
import com.plian.system.vo.pf.*;
import com.plian.system.wrapper.pf.BaseWelfareExpendWrapper;
import com.plian.system.wrapper.pf.WelfareExpendWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

import static com.plian.system.constant.sys.FormStatusConstant.UNREVIEWED;

/**
 * 职工福利费支出明细主表 服务实现类
 *
 * @author
 * @since 2019-09-27
 */
@Slf4j
@Service
@AllArgsConstructor
public class BaseWelfareExpendServiceImpl extends BaseServiceImpl<BaseWelfareExpendMapper, BaseWelfareExpend> implements IBaseWelfareExpendService, BaseFlowService {

	private FormWorkflowService formWorkflowService;

	private IFormCodeService formCodeService;

	private IWelfareExpendService welfareExpendService;

	private BaseInfoService baseInfoService;

	private OrgzationService orgzationService;

	private WelfareExpendMapper welfareExpendMapper;

	private IWelfareSummaryRelationService welfareSummaryRelationService;

	private WelfareSummaryRelationMapper welfareSummaryRelationMapper;

	private BaseWelfareExpendWrapper baseWelfareExpendWrapper;

	private WelfareExpendWrapper welfareExpendWrapper;

	private WorkflowTwoService workflowTwoService;

	@Override
	public boolean saveOrUpdate(BaseWelfareExpend baseWelfareExpend) {

		if (!Optional.ofNullable(baseWelfareExpend.getStatus()).isPresent()) {
			baseWelfareExpend.setStatus(FormStatusConstant.UNREVIEWED);
		}
		if (!Optional.ofNullable(baseWelfareExpend.getId()).isPresent()) {
			baseWelfareExpend.setCode(formCodeService.getCode(FormTypeConstant.PF_BASE_WELFARE_EXPEND));
			baseWelfareExpend.setFormType(String.valueOf(FormTypeConstant.PF_BASE_WELFARE_EXPEND));
		}

		return super.saveOrUpdate(baseWelfareExpend);
	}

	@Override
	@Transactional(rollbackFor=RuntimeException.class)
	public boolean deleteLogic(List<Long> ids) {
		List<Long> removeIds = new ArrayList<>();
		for (Long id : ids) {
			BaseWelfareExpend baseWelfareExpend = getById(id);
			if (baseWelfareExpend == null) {
				return false;
			} else if (baseWelfareExpend.getStatus() != null &&
					(baseWelfareExpend.getStatus() != FormStatusConstant.STASH && baseWelfareExpend.getStatus() != FormStatusConstant.UNREVIEWED
							&& baseWelfareExpend.getStatus() != FormStatusConstant.REJECT)) {
				return false;
			}

			if (Optional.ofNullable(baseWelfareExpend.getType()).isPresent() && baseWelfareExpend.getType() == 2){
				BaseWelfareExpend otherBase = getOne(new LambdaQueryWrapper<BaseWelfareExpend>()
						.eq(BaseWelfareExpend::getFillingYear, baseWelfareExpend.getFillingYear())
						.eq(BaseWelfareExpend::getFillingUnitId, baseWelfareExpend.getFillingUnitId())
						.eq(BaseWelfareExpend::getType, 1));
				if (Optional.ofNullable(otherBase).isPresent()){
					formWorkflowService.deleteProcessInstance(String.valueOf(otherBase.getId()));
					removeIds.add(otherBase.getId());
				}

			}
			removeIds.add(id);
			formWorkflowService.deleteProcessInstance(String.valueOf(id));
		}

		boolean result = super.deleteLogic(removeIds);
		if (result){
			welfareExpendService.deleteByParentId(removeIds);
			welfareSummaryRelationService.deleteByBaseId(removeIds);
		}

		return result;
	}

	@Override
	public HashMap<String,Object> commit(String id) {
		handleStatus(Long.valueOf(id), FormStatusConstant.FLOW);

		//将需要提交的流程变量返回，用于工作流侧
		return new HashMap<String,Object>();
	}

	@Override
	public Boolean finish(String id) {
		return handleStatus(Long.valueOf(id), FormStatusConstant.FINISH);
	}

	@Override
	public Boolean reject(String id, int formState, String comment) {
		return handleStatus(Long.valueOf(id), formState);
	}

	@Override
	public String checkMonth(BaseWelfareExpend baseWelfareExpend) {
		LambdaQueryWrapper<BaseWelfareExpend> queryWrapper = new LambdaQueryWrapper<>();
		if (!Optional.ofNullable(baseWelfareExpend.getFillingYear()).isPresent()) {
			return "填报年度为空";
		}
		if (!Optional.ofNullable(baseWelfareExpend.getFillingUnitId()).isPresent()){
			return "填报单位为空";
		}
		queryWrapper.eq(BaseWelfareExpend::getType, baseWelfareExpend.getType());
		queryWrapper.eq(BaseWelfareExpend::getFillingUnitId,baseWelfareExpend.getFillingUnitId());
		queryWrapper.eq(BaseWelfareExpend::getFillingYear, baseWelfareExpend.getFillingYear());
		BaseWelfareExpend one = getOne(queryWrapper);
		if (!Optional.ofNullable(one).isPresent()){
			return null;
		}
		if (one.getId().equals(baseWelfareExpend.getId())){
			return null;
		}
		return "该年度已填报";
	}


	/**
	 * 统一处理状态机事件方法
	 *
	 * @param id          主键
	 * @param updateStatus  更新状态
	 * @return boolean
	 */
	private Boolean handleStatus(Long id, int updateStatus) {
		try {
			BaseWelfareExpend baseWelfareExpend = getById(id);
			/**
			 * 设置审批人和审批时间
			 */
			if (updateStatus == FormStatusConstant.FINISH){
				baseWelfareExpend.setApprovedUser(TokenUtil.getTokenUserId());
				Date now = DateUtil.now();
				baseWelfareExpend.setApprovedTime(now);
			}
			baseWelfareExpend.setStatus(updateStatus);
			updateById(baseWelfareExpend);
			return true;
		} catch (Exception e) {
			log.error(ExceptionUtils.getFullStackTrace(e));
			return false;
		}
	}


	@Override
	public List<PageData> findByIds(List<String> formIds) {
		LambdaQueryWrapper<BaseWelfareExpend> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.in(BaseWelfareExpend::getId, Func.toLongList(StringUtils.join(formIds, StringPool.COMMA)));
		List<BaseWelfareExpend> baseWelfareExpends = list(queryWrapper);
		List<BaseWelfareExpendVO> baseWelfareExpendVOS= baseWelfareExpendWrapper.entityToVO(baseWelfareExpends);
		List<PageData> pageDataList = new ArrayList<>();
		try{
			if (CollectionUtil.isNotEmpty(baseWelfareExpendVOS)){
				for (BaseWelfareExpendVO vo : baseWelfareExpendVOS){
					PageData pd = new PageData();
					pd.put("id", vo.getId());
					pd.put("UNITNAME", vo.getFillingUnitName());
					pd.put("APPLICANTNAME", vo.getCreateUserName());
					pd.put("applicantId", vo.getCreateUser());
					pd.put("applyOrganizationId", vo.getFillingUnitId());
					pd.put("formType", FormTypeConstant.PF_BASE_WELFARE_EXPEND);
					pd.put("orgName", vo.getFillingUnitName());
					pageDataList.add(pd);
				}
			}

			return pageDataList;
		} catch (Exception e) {
			log.error(ExceptionUtils.getFullStackTrace(e));
		}
		return pageDataList;
	}

	@Override
	public List<Integer> getFormType() {
		return Collections.singletonList(FormTypeConstant.PF_BASE_WELFARE_EXPEND);
	}

	@Override
	@Transactional(rollbackFor=RuntimeException.class)
	public boolean submit(BaseWelfareExpend baseWelfareExpend) {
		boolean result = saveOrUpdate(baseWelfareExpend);
		if (result){

			List<WelfareExpend> welfareExpends = baseWelfareExpend.getWelfareExpends();
			if (CollectionUtil.isNotEmpty(welfareExpends)){
				for (WelfareExpend welfareExpend : welfareExpends){
					if (welfareExpend.getId() != null &&
							Optional.ofNullable(welfareExpend.getIsDeleted()).isPresent() && welfareExpend.getIsDeleted().intValue() == 1) {
						welfareExpendService.removeById(welfareExpend.getId());
					}else {
						welfareExpend.setBaseWelfareExpendId(baseWelfareExpend.getId());
						welfareExpendService.saveOrUpdate(welfareExpend);
					}
				}
			}
			List<Long> childIds = baseWelfareExpend.getChildIds();
			if (CollectionUtil.isNotEmpty(childIds)){
				welfareSummaryRelationService.submit(baseWelfareExpend.getId(), childIds);
			}

			if(baseWelfareExpend.getStatus() == 3){
				// 反审核
				goBackToStash(String.valueOf(baseWelfareExpend.getId()));
				workflowTwoService.goBackToStash(String.valueOf(baseWelfareExpend.getId()), FormTypeConstant.HR_STAFFFILES_FORM);
			}
		}
		return result;
	}

	@Override
	public R<BaseWelfareExpendVO> getDetailObj(BaseWelfareExpendVO baseWelfareExpendVO) {
		if(!Optional.ofNullable(baseWelfareExpendVO).isPresent()){
			return R.fail();
		}

		PageData pd = new PageData();
		ObjectMapper mapper = new ObjectMapper();
		String json = JSON.toJSONStringWithDateFormat(baseWelfareExpendVO, DateUtil.PATTERN_DATETIME);
		try {
			pd.putAll(mapper.readValue(json, new TypeReference<HashMap<String, String>>() {}));
		}catch (Exception e) {
			log.error(ExceptionUtils.getFullStackTrace(e));
			return R.error();
		}
		List<WelfareExpendVO> welfareExpendVOS = welfareExpendWrapper.entityToVO(welfareExpendService
				.list(new LambdaQueryWrapper<WelfareExpend>().eq(WelfareExpend::getBaseWelfareExpendId, baseWelfareExpendVO.getId())));
		Collections.sort(welfareExpendVOS, (a, b) -> Integer.valueOf(a.getWelfareCategoryId()).compareTo(Integer.valueOf(b.getWelfareCategoryId())));
		baseWelfareExpendVO.setWelfareExpendVOS(welfareExpendVOS);
		return R.data(baseWelfareExpendVO);
	}

	@Override
	public void goBackToStash(String formId) {
		handleStatus(Long.valueOf(formId), UNREVIEWED);
	}

	@Override
	public  List<WelfareExpend> getLastMonthObj(String fillingUnitId, String fillingMonth) {
		Calendar c = Calendar.getInstance();
		Date lastDate = DateUtil.parse(fillingMonth, DateUtil.PATTERN_MONTH);
		c.setTime(lastDate);
		c.add(Calendar.MONTH, -1);
		String lastMonth = DateUtil.format(c.getTime(), DateUtil.PATTERN_MONTH);
		BaseWelfareExpend last = null;

		if (DateUtil.isTheSameYear(lastDate, c.getTime())) {
			last = getOne(new LambdaQueryWrapper<BaseWelfareExpend>()
					.eq(BaseWelfareExpend::getFillingUnitId, fillingUnitId)
					.eq(BaseWelfareExpend::getFillingMonth, lastMonth)
					.eq(BaseWelfareExpend::getType, 1));

		}

		List<WelfareExpend> welfareExpends = new ArrayList<>();
		if (Optional.ofNullable(last).isPresent()){
			welfareExpends = welfareExpendService.list(new LambdaQueryWrapper<WelfareExpend>()
					.eq(WelfareExpend::getBaseWelfareExpendId, last.getId()));
		}

		return welfareExpends;

	}

//	@Override
//	public ReportReturnVO yearStatistics(BaseWelfareExpendDTO baseWelfareExpendDTO) {
//		List<BaseWelfareExpend> baseList = list(new QueryWrapper<BaseWelfareExpend>()
//				.eq("status", FormStatusConstant.FINISH)
//				.eq("type", 2)
//				.in("filling_unit_id", baseWelfareExpendDTO.getFillingUnitIds())
//				.like("filling_month", baseWelfareExpendDTO.getFillingYear()));
//		List<WelfareMonthStatisticsVO> results = initSummary();
//		if (CollectionUtil.isNotEmpty(baseList)){
//			Map<Long, List<BaseWelfareExpend>> baseMap = baseList.stream().collect(Collectors.groupingBy(BaseWelfareExpend::getId));
//			List<WelfareExpend> welfareExpends = welfareExpendService.list(new QueryWrapper<WelfareExpend>()
//					.in("base_welfare_expend_id", baseList.stream().map(BaseWelfareExpend::getId).collect(Collectors.toList())));
//			// 按福利类型分类
//			Map<String, List<WelfareExpend>> map = welfareExpends.stream().collect(Collectors.groupingBy(WelfareExpend::getWelfareCategoryId));
//			//合计 倒序计算
//			BigDecimal allTotal = new BigDecimal(0);
//
//			for (int i = results.size()-1; i>=0; i--){
//				WelfareMonthStatisticsVO result = results.get(i);
//				if (map.containsKey(result.getWelfareCategoryId())){
//					BigDecimal total = new BigDecimal(0);
//					for (WelfareExpend welfareExpend : map.get(result.getWelfareCategoryId())){
//						setGrantAmount(welfareExpend, result, baseMap.get(welfareExpend.getBaseWelfareExpendId()).get(0).getFillingMonth());
//						if (Optional.ofNullable(welfareExpend.getGrantAmount()).isPresent()){
//							total = total.add(welfareExpend.getGrantAmount());
//						}
//					}
//					// 比例
//					if (i == results.size()-1){
//						result.setProportion(new BigDecimal(100));
//						allTotal = total;
//					}else {
//						result.setProportion(BigDecimalUtil.divide(total, allTotal, 2, BigDecimal.ROUND_HALF_UP, 100));
//					}
//					result.setCumulativeGrantAmount(total);
//				}
//			}
//		}
//
//		ReportReturnVO reportReturnVO = new ReportReturnVO();
//		ReportVO reportVO = new ReportVO();
//
//		reportVO
//				.addHeader(HeaderVO.builder().key("welfareCategoryName").title("项目名称").build())
//				.addHeader(HeaderVO.builder().key("cumulativeGrantAmount").title("累计发生额").build())
//				.addHeader(HeaderVO.builder().key("januaryGrantAmount").title("1月发生额").build())
//				.addHeader(HeaderVO.builder().key("februaryGrantAmount").title("2月发生额").build())
//				.addHeader(HeaderVO.builder().key("marchGrantAmount").title("3月发生额").build())
//				.addHeader(HeaderVO.builder().key("aprilGrantAmount").title("4月发生额").build())
//				.addHeader(HeaderVO.builder().key("mayGrantAmount").title("5月发生额").build())
//				.addHeader(HeaderVO.builder().key("juneGrantAmount").title("6月发生额").build())
//				.addHeader(HeaderVO.builder().key("julyGrantAmount").title("7月发生额").build())
//				.addHeader(HeaderVO.builder().key("augustGrantAmount").title("8月发生额").build())
//				.addHeader(HeaderVO.builder().key("septemberGrantAmount").title("9月发生额").build())
//				.addHeader(HeaderVO.builder().key("octoberGrantAmount").title("10月发生额").build())
//				.addHeader(HeaderVO.builder().key("novemberGrantAmount").title("11月发生额").build())
//				.addHeader(HeaderVO.builder().key("decemberGrantAmount").title("12月发生额").build())
//				.addHeader(HeaderVO.builder().key("proportion").title("比例%").build());
//		reportVO.setData(results);
//		reportReturnVO.setGrids(reportVO);
//		return reportReturnVO;
//	}

	@Override
	public ObjResult tree(BaseWelfareExpend baseWelfareExpend) {
		String fillingYear = baseWelfareExpend.getFillingYear();
		if (StringUtil.isBlank(fillingYear)){
			fillingYear = DateUtil.format(DateUtil.now(), DateUtil.PATTERN_YEAR);
		}
		LambdaQueryWrapper<BaseWelfareExpend> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(BaseWelfareExpend::getFillingYear, fillingYear);
		List<BaseWelfareExpend> baseWelfareExpends = list(queryWrapper);
		List<PageData> orgList = orgzationService.getSubordinate().getList();
		if (CollectionUtil.isEmpty(orgList)){
			return new ObjResult(CustomCode.builder().message("企业树初始化失败").code(1999).success(false).build());
		}

		Map<String, List<BaseWelfareExpend>> oneMap = new HashMap<>();
		Map<String, List<BaseWelfareExpend>> twoMap = new HashMap<>();

		if (CollectionUtil.isNotEmpty(baseWelfareExpends)){
			oneMap = baseWelfareExpends.stream().filter(data -> data.getType() != null && data.getType() == 1)
					.collect(Collectors.groupingBy(BaseWelfareExpend::getFillingUnitId));
			twoMap = baseWelfareExpends.stream().filter(data -> data.getType() != null && data.getType() == 2)
					.collect(Collectors.groupingBy(BaseWelfareExpend::getFillingUnitId));
		}

		List<WelfareExpendTreeVO> tree = setTree(orgList, oneMap, twoMap);
		WelfareExpendTreeVO result = new WelfareExpendTreeVO();
		if (CollectionUtil.isNotEmpty(tree)){
			result = tree.get(0);
		}
		ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
		PageData pd = new PageData();
		pd.put("tree", result);
		objResult.setPageData(pd);
		return objResult;
	}

//	@Override TODO DEL
//	public ObjResult getSummaryObj(BaseWelfareExpend baseWelfareExpend) {
//		String fillingYear = baseWelfareExpend.getFillingYear();
//		if (StringUtil.isBlank(fillingYear)){
//			return new ObjResult(CustomCode.builder().message("填报年度为空").code(1999).success(false).build());
//		}
//		String fillingUnitId = baseWelfareExpend.getFillingUnitId();
//		if (StringUtil.isBlank(fillingUnitId)){
//			return new ObjResult(CustomCode.builder().message("填报单位为空").code(1999).success(false).build());
//		}
//
//		List<String> fillingUnitIds = getChildIds(fillingUnitId);
//		fillingUnitIds.add(fillingUnitId);
//
//		ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
//		PageData pd = new PageData();
//		List<WelfareExpendVO> summaryList = summary(fillingYear, fillingUnitIds);
//		pd.put("welfareExpendVOS", summaryList);
//		objResult.setPageData(pd);
//		return objResult;
//	}


	@Override
	public ListResult<PageData> treeList(Query query) {
		List<SearchEntity> entityList = query.getSearch();
		if (query.getAscs()==null&&query.getDescs()==null){
			query.setDescs("filling_year");
		}
		QueryWrapper<BaseWelfareExpend> queryWrapper = SearchParamEntiy.getQueryWrapper(
				Condition.getQueryWrapper(new BaseWelfareExpend()), entityList
		);
		queryWrapper.eq("create_company_id", TokenUtil.getTokenOrgId());

		if (orgzationService.isParent(TokenUtil.getTokenOrgId())){
			queryWrapper.eq("type", 2);
		}else {
			queryWrapper.eq("type", 1);
		}

		IPage<BaseWelfareExpend> pages = page(Condition.getPage(query), queryWrapper);
		List<BaseWelfareExpendVO> baseWelfareExpendVOS = baseWelfareExpendWrapper.entityToVO(pages.getRecords());
		List<PageData> pageDataList = new ArrayList<>();
		if (CollectionUtil.isNotEmpty(baseWelfareExpendVOS)){
			for (BaseWelfareExpendVO vo : baseWelfareExpendVOS){
				PageData pd = new PageData();
				pd.put("createUser", vo.getCreateUser());
				pd.put("fillingUnitId", vo.getFillingUnitId());
				pd.put("fillingUnitName", vo.getFillingUnitName());
				pd.put("fillingYear", vo.getFillingYear());
				pd.put("baseWelfareExpendId", vo.getId().toString());
				if (vo.getType() == 1){
					pd.put("typeName", "单户表");
				}else {
					pd.put("typeName", "集团合并表");
				}
				pd.put("formType", FormTypeConstant.PF_BASE_WELFARE_EXPEND);
				pd.put("type", vo.getType());
				pd.put("status", vo.getStatus());
				pageDataList.add(pd);
			}
		}
		ListResult<PageData> listResult = new ListResult<>(CommonCode.SUCCESS);
		listResult.setList(pageDataList);
		listResult.setTotal(Long.valueOf(pages.getTotal()).intValue());
		return listResult;

	}

	@Override
	@Transactional(rollbackFor=RuntimeException.class)
	public ObjResult addTree(BaseWelfareExpend baseWelfareExpend) {
		String fillingYear = baseWelfareExpend.getFillingYear();
		if (StringUtil.isBlank(fillingYear)){
			return new ObjResult(CustomCode.builder().message("填报年度为空").code(1999).success(false).build());
		}

		String fillingUnitId = TokenUtil.getTokenOrgId();
		//单表数据
		BaseWelfareExpend oneOldBase = getOne(new LambdaQueryWrapper<BaseWelfareExpend>()
				.eq(BaseWelfareExpend::getFillingYear, fillingYear)
				.eq(BaseWelfareExpend::getFillingUnitId, fillingUnitId)
				.eq(BaseWelfareExpend::getType, 1));
		boolean result = true;
		if (!Optional.ofNullable(oneOldBase).isPresent()){
			List<WelfareExpend> oneChildList = new ArrayList<>();
			BaseWelfareExpend oneBase = BaseWelfareExpend.builder().fillingDate(DateUtil.now())
					.fillingYear(fillingYear).fillingUnitId(fillingUnitId).type(1).build();
			result = this.saveOrUpdate(oneBase);
			HashMap<String, Object> processVariable = new HashMap<>();
			formWorkflowService.startProcessAndSimulate(String.valueOf(oneBase.getId()),oneBase.getFormType(),processVariable);
			oneChildList.addAll(init(oneBase.getId()));
			if (CollectionUtil.isNotEmpty(oneChildList)){
				welfareExpendService.saveBatch(oneChildList);
			}
		}


		//合计数据
		List<String> childIds = getChildIds(fillingUnitId);
		if (CollectionUtil.isNotEmpty(childIds)) {

			BaseWelfareExpend twoOldBase = getOne(new LambdaQueryWrapper<BaseWelfareExpend>()
					.eq(BaseWelfareExpend::getFillingYear, fillingYear)
					.eq(BaseWelfareExpend::getFillingUnitId, fillingUnitId)
					.eq(BaseWelfareExpend::getType, 2));
			if (!Optional.ofNullable(twoOldBase).isPresent()){
				// 该企业有下级 创建合计数据
				BaseWelfareExpend twoBase = BaseWelfareExpend.builder().fillingDate(DateUtil.now())
						.fillingYear(fillingYear).fillingUnitId(fillingUnitId).type(2).build();
				this.saveOrUpdate(twoBase);
				HashMap<String, Object> processVariable = new HashMap<>();
				formWorkflowService.startProcessAndSimulate(String.valueOf(twoBase.getId()),twoBase.getFormType(),processVariable);
				List<WelfareExpend> twoChildList = new ArrayList<>();
				twoChildList.addAll(init(twoBase.getId()));
				if (CollectionUtil.isNotEmpty(twoChildList)){
					welfareExpendService.saveBatch(twoChildList);
				}
			}

		}

		return result ? new ObjResult(CommonCode.SUCCESS) : new ObjResult(CommonCode.FAIL);
	}

	@Override
	public ObjResult childList(BaseWelfareExpend baseWelfareExpend) {
		String fillingYear = baseWelfareExpend.getFillingYear();
		if (StringUtil.isBlank(fillingYear)){
			return new ObjResult(CustomCode.builder().message("填报年度为空").code(1999).success(false).build());
		}
		String fillingUnitId = baseWelfareExpend.getFillingUnitId();
		if (StringUtil.isBlank(fillingUnitId)){
			return new ObjResult(CustomCode.builder().message("填报单位为空").code(1999).success(false).build());
		}

		//本级单户表
		List<BaseWelfareExpendVO> results = new ArrayList<>();
		LambdaQueryWrapper<BaseWelfareExpend> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(BaseWelfareExpend::getFillingYear, fillingYear);
		queryWrapper.eq(BaseWelfareExpend::getFillingUnitId, fillingUnitId);
		queryWrapper.eq(BaseWelfareExpend::getType, 1);
		BaseWelfareExpendVO baseVO = baseWelfareExpendWrapper.entityToVO(getOne(queryWrapper));
		if (Optional.ofNullable(baseVO).isPresent()){
			baseVO.setTypeName("单户表");
			results.add(baseVO);
		}

		//下级合计表和单户表 不包括孙子级
		List<PageData> childList = orgzationService.getChildrenByPId(fillingUnitId);
		if (CollectionUtil.isNotEmpty(childList)){
			List<String> childIds = new ArrayList<>();
			Map<String, String> childOrgMap = new HashMap<>();
			for (PageData child : childList){
				childIds.add((String)child.get("id"));
				childOrgMap.put((String)child.get("id"), (String)child.get("name"));
			}

			List<BaseWelfareExpend> childBaseList = list(new LambdaQueryWrapper<BaseWelfareExpend>()
					.eq(BaseWelfareExpend::getFillingYear, fillingYear).in(BaseWelfareExpend::getFillingUnitId, childIds));
			if (CollectionUtil.isNotEmpty(childBaseList)){

				// 剔除有合并表数据企业的单表数据
				Map<String, List<BaseWelfareExpend>> baseWelfareExpendMap = childBaseList.stream().collect(Collectors.groupingBy(BaseWelfareExpend::getFillingUnitId));
				List<Long> delId = new ArrayList<>();
				baseWelfareExpendMap.forEach((k, v) ->{
					if (CollectionUtil.isNotEmpty(v) && v.size() > 1){
						for (BaseWelfareExpend child : v){
							if (Optional.ofNullable(child.getType()).isPresent() && child.getType() == 1){
								delId.add(child.getId());
							}
						}
					}
				});

				for (BaseWelfareExpend childBase : childBaseList){
					if (!delId.contains(childBase.getId())){
						BaseWelfareExpendVO baseWelfareExpendVO = new BaseWelfareExpendVO();
						baseWelfareExpendVO.setId(childBase.getId());
						baseWelfareExpendVO.setFillingUnitId(childBase.getFillingUnitId());
						baseWelfareExpendVO.setFillingUnitName(childOrgMap.get(childBase.getFillingUnitId()));
						baseWelfareExpendVO.setFillingYear(childBase.getFillingYear());
						baseWelfareExpendVO.setType(childBase.getType());
						baseWelfareExpendVO.setStatus(childBase.getStatus());
						if (Optional.ofNullable(childBase.getType()).isPresent()){
							if (childBase.getType() == 1){
								baseWelfareExpendVO.setTypeName("单户表");
							}else if (childBase.getType() == 2){
								baseWelfareExpendVO.setTypeName("集团合并表");
							}
						}
						results.add(baseWelfareExpendVO);
					}
				}
			}
		}

		PageData pd = new PageData();
		pd.put("childList", results);
		ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
		objResult.setPageData(pd);

		return objResult;
	}

	@Override
	public ObjResult childSummary(BaseWelfareExpend baseWelfareExpend) {
		List<Long> childIds = baseWelfareExpend.getChildIds();
		if (CollectionUtil.isEmpty(childIds)){
			return new ObjResult(CustomCode.builder().message("未勾选项目").code(1999).success(false).build());
		}

		ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
		List<WelfareExpendVO> welfareExpendVOS = welfareExpendMapper.summaryByBaseIds(childIds);
		setVO(welfareExpendVOS);
		PageData pd = new PageData();
		pd.put("childIds", childIds.stream().map(childId -> String.valueOf(childId)).collect(Collectors.toList()));
		pd.put("welfareExpendVOS", welfareExpendVOS);
		objResult.setPageData(pd);

		return objResult;
	}

	@Override
	public ObjResult summaryDetail(BaseWelfareExpendDTO baseWelfareExpendDTO) {
		ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
		PageData pd = new PageData();
		List<WelfareExpendSummaryDetailVO> details =  welfareSummaryRelationMapper.summaryDetail(baseWelfareExpendDTO.getBaseWelfareExpendId(),
				baseWelfareExpendDTO.getWelfareCategoryId(), baseWelfareExpendDTO.getColumnName());
		if (CollectionUtil.isNotEmpty(details)){
			for (WelfareExpendSummaryDetailVO vo : details){
				if (Optional.ofNullable(vo.getType()).isPresent()){
					if (vo.getType() == 1){
						vo.setTypeName("单户表");
					}else if (vo.getType() == 2){
						vo.setTypeName("集团合并表");
					}
				}
			}
		}
		pd.put("details", details);
		objResult.setPageData(pd);
		return objResult;
	}

	/**
	 * 单表:子表数据生成
	 * @param baseId
	 * @return
	 */
	private List<WelfareExpend> init(Long baseId){
		Map<String, String> welfareCategoryMap = baseInfoService.getChildMap(ValueSetConstant.WELFARE_CATEGORY);
		List<WelfareExpend> initList = new ArrayList<>();
		welfareCategoryMap.forEach((k,v) ->{
				WelfareExpend init = new WelfareExpend();
				init.setWelfareCategoryId(k);
				init.setBaseWelfareExpendId(baseId);
				init.setIsDeleted(0);
				init.setCreateUser(TokenUtil.getTokenUserId());
				init.setCreateTime(DateUtil.now());
				init.setCreateCompanyId(TokenUtil.getTokenOrgId());
				initList.add(init);
			});
		Collections.sort(initList, (a, b) -> Integer.valueOf(a.getWelfareCategoryId()).compareTo(Integer.valueOf(b.getWelfareCategoryId())));
		return initList;
	}

	/**
	 * 递归 树的初始化
	 * @param orgList
	 * @param oneMap
	 * @param twoMap
	 * @return
	 */
	private List<WelfareExpendTreeVO> setTree(List<PageData> orgList, Map<String, List<BaseWelfareExpend>> oneMap, Map<String, List<BaseWelfareExpend>> twoMap){
		List<WelfareExpendTreeVO> tree = new ArrayList<>();
		for (PageData org : orgList){
			List<PageData> orgChildren = (List<PageData>)org.get("children");
			String fillingUnitId = (String)org.get("id");
			String fillingUnitName = (String)org.get("name");
			String orgCode =  (String)org.get("orgCode");
			String orgType = org.getString("type");
			BaseWelfareExpend oneBase = new BaseWelfareExpend();
			if (oneMap.containsKey(fillingUnitId)){
				oneBase = oneMap.get(fillingUnitId).get(0);
			}
			if (CollectionUtil.isNotEmpty(orgChildren)){
				WelfareExpendTreeVO result = WelfareExpendTreeVO.builder().fillingUnitId(fillingUnitId)
						.status(FormStatusConstant.NOFILLING)
						.fillingUnitName(fillingUnitName).type(3).build();
				List<WelfareExpendTreeVO> children = new ArrayList<>();
				//判断该单位是否为集团和下级
				if (StringUtil.isNotBlank(orgCode) && "2".equals(orgType)){
					result.setType(2);
					result.setTypeName("集团合并表");
					//自己节点为合计表
					if (twoMap.containsKey(fillingUnitId)){
						BaseWelfareExpend twoBase = twoMap.get(fillingUnitId).get(0);
						result.setStatus(twoBase.getStatus());
						result.setFillingYear(twoBase.getFillingYear());
						result.setFormType(String.valueOf(FormTypeConstant.PF_BASE_WELFARE_EXPEND));
						result.setBaseWelfareExpendId(twoBase.getId());
					}
					//子节点第一个为 单表
					WelfareExpendTreeVO child = WelfareExpendTreeVO.builder().fillingUnitId(fillingUnitId).fillingUnitName(fillingUnitName)
							.fillingYear(oneBase.getFillingYear()).baseWelfareExpendId(oneBase.getId()).status(oneBase.getStatus())
							.formType(String.valueOf(FormTypeConstant.PF_BASE_WELFARE_EXPEND)).typeName("单户表").type(1)
							.build();
					if (child.getStatus() == null){
						child.setStatus(FormStatusConstant.NOFILLING);
					}
					children.add(child);
				}

				tree.add(result);
				children.addAll(setTree(orgChildren, oneMap, twoMap));
				result.setChildren(children);
			}else {
				//自己节点为 单表
				WelfareExpendTreeVO result = WelfareExpendTreeVO.builder().fillingUnitId(fillingUnitId).fillingUnitName(fillingUnitName)
						.fillingYear(oneBase.getFillingYear()).typeName("单户表")
						.formType(String.valueOf(FormTypeConstant.PF_BASE_WELFARE_EXPEND))
						.baseWelfareExpendId(oneBase.getId()).type(1).status(oneBase.getStatus())
						.build();
				if (result.getStatus() == null){
					result.setStatus(FormStatusConstant.NOFILLING);
				}
				tree.add(result);
			}
		}
		return tree;
	}

//	/**
//	 * 赋值
//	 * @param welfareExpend
//	 * @param result
//	 * @param fillingMonth
//	 */
//	private void setGrantAmount(WelfareExpend welfareExpend, WelfareMonthStatisticsVO result, String fillingMonth){
//		int month = Integer.valueOf(fillingMonth.split("-")[1]);
//		switch (month){
//			case 1:
//				result.setJanuaryGrantAmount(welfareExpend.getGrantAmount());
//				break;
//			case 2:
//				result.setFebruaryGrantAmount(welfareExpend.getGrantAmount());
//				break;
//			case 3:
//				result.setMarchGrantAmount(welfareExpend.getGrantAmount());
//				break;
//			case 4:
//				result.setAprilGrantAmount(welfareExpend.getGrantAmount());
//				break;
//			case 5:
//				result.setMayGrantAmount(welfareExpend.getGrantAmount());
//				break;
//			case 6:
//				result.setJuneGrantAmount(welfareExpend.getGrantAmount());
//				break;
//			case 7:
//				result.setJulyGrantAmount(welfareExpend.getGrantAmount());
//				break;
//			case 8:
//				result.setAugustGrantAmount(welfareExpend.getGrantAmount());
//				break;
//			case 9:
//				result.setSeptemberGrantAmount(welfareExpend.getGrantAmount());
//				break;
//			case 10:
//				result.setOctoberGrantAmount(welfareExpend.getGrantAmount());
//				break;
//			case 11:
//				result.setNovemberGrantAmount(welfareExpend.getGrantAmount());
//				break;
//			case 12:
//				result.setDecemberGrantAmount(welfareExpend.getGrantAmount());
//				break;
//			default:
//				break;
//
//		}
//	}

	/**
	 * 统计数组初始化
	 * @return
	 */
	private List<WelfareMonthStatisticsVO> initSummary(){
		Map<String, String> welfareCategoryMap = baseInfoService.getChildMap(ValueSetConstant.WELFARE_CATEGORY);
		List<WelfareMonthStatisticsVO> initList = new ArrayList<>();
		welfareCategoryMap.forEach((k,v) ->{
			WelfareMonthStatisticsVO init = WelfareMonthStatisticsVO.builder().welfareCategoryId(k).welfareCategoryName(v).build();
			initList.add(init);
		});
		Collections.sort(initList, (a, b) -> Integer.valueOf(a.getWelfareCategoryId()).compareTo(Integer.valueOf(b.getWelfareCategoryId())));
		return initList;
	}

//	/**
//	 * 初始化列表 年月
//	 * @param baseId
//	 * @param welfareExpends
//	 * @return
//	 */
//	private List<WelfareExpendVO> lastInit(Long baseId, List<WelfareExpend> welfareExpends){
//		Map<String, String> welfareCategoryMap = baseInfoService.getChildMap(ValueSetConstant.WELFARE_CATEGORY);
//		List<WelfareExpendVO> initList = new ArrayList<>();
//		welfareCategoryMap.forEach((k,v) ->{
//			WelfareExpendVO init = new WelfareExpendVO();
//			init.setWelfareCategoryId(k);
//			init.setWelfareCategoryName(v);
//			init.setBaseWelfareExpendId(baseId);
//			init.setIsDeleted(0);
//			init.setCreateUser(TokenUtil.getTokenUserId());
//			init.setCreateTime(DateUtil.now());
//			init.setCreateCompanyId(TokenUtil.getTokenOrgId());
//			if (CollectionUtil.isNotEmpty(welfareExpends)){
//				for (WelfareExpend welfareExpend : welfareExpends){
//					if (k.equals(welfareExpend.getWelfareCategoryId())){
//						init.setLastGrantAmount(welfareExpend.getCumulativeGrantAmount());
//						init.setCumulativeGrantAmount(welfareExpend.getCumulativeGrantAmount());
//						init.setProportion(welfareExpend.getProportion());
//						break;
//					}
//				}
//			}
//			initList.add(init);
//		});
//		Collections.sort(initList, (a, b) -> Integer.valueOf(a.getWelfareCategoryId()).compareTo(Integer.valueOf(b.getWelfareCategoryId())));
//		return initList;
//
//	}

	/**
	 * 获取子企业id
	 * @param fillingUnitId
	 * @return
	 */
	private List<String> getChildIds(String fillingUnitId){
		List<String> fillingUnitIds = new ArrayList<>();
		try {
			List<PageData> children = orgzationService.getChlidList(fillingUnitId);
			if (CollectionUtil.isNotEmpty(children)){
				for (PageData child : children){
					if (!fillingUnitId.equals(child.get("id"))){
						fillingUnitIds.add((String)child.get("id"));
					}

				}
			}
		}catch (Exception e) {
			log.error(ExceptionUtils.getFullStackTrace(e));
		}
		return fillingUnitIds;
	}

	/**
	 * 合计
	 * @param fillingYear
	 * @param fillingUnitIds
	 * @return
	 */
	private List<WelfareExpendVO> summary(String fillingYear, List<String> fillingUnitIds){
		List<WelfareExpendVO> welfareExpendVOS = welfareExpendMapper.summary(fillingYear, fillingUnitIds);
		setVO(welfareExpendVOS);
		return welfareExpendVOS;
	}

	/**
	 * 计算占比 福利类型名称赋值
	 * @param welfareExpendVOS
	 */
	private void setVO(List<WelfareExpendVO> welfareExpendVOS){
		if (CollectionUtil.isNotEmpty(welfareExpendVOS)){
			Map<String, String> welfareCategoryMap = baseInfoService.getChildMap(ValueSetConstant.WELFARE_CATEGORY);
			WelfareExpendVO end = welfareExpendVOS.get(welfareExpendVOS.size() - 1);
			end.setWelfareCategoryName(welfareCategoryMap.get(end.getWelfareCategoryId()));
			end.setProportion(new BigDecimal(100));
			for (int i = 0; i < welfareExpendVOS.size() - 1; i++){
				WelfareExpendVO welfareExpendVO = welfareExpendVOS.get(i);
				welfareExpendVO.setProportion(BigDecimalUtil.divide(welfareExpendVO.getYearGrantAmount(),
						end.getYearGrantAmount(), 2, BigDecimal.ROUND_HALF_UP, 100));
				welfareExpendVO.setWelfareCategoryName(welfareCategoryMap.get(welfareExpendVO.getWelfareCategoryId()));
			}
		}
		Collections.sort(welfareExpendVOS, (a, b) -> Integer.valueOf(a.getWelfareCategoryId()).compareTo(Integer.valueOf(b.getWelfareCategoryId())));
	}

	/**
	 * 导出报表
	 *
	 * @param
	 * @throws Exception
	 */
	@Override
	public void exportExcel(BaseWelfareExpendVO baseWelfareExpendVO, HttpServletResponse response)  {
		try {
			String fname = "职工福利费支出明细表";
			OutputStream os = response.getOutputStream();//取得输出流
			response.reset();//清空输出流
			//下面是对中文文件名的处理
			response.setCharacterEncoding("UTF-8");//设置相应内容的编码格式
			//读取系统中的模板
			fname = java.net.URLEncoder.encode(fname, "UTF-8");
			response.setHeader("Content-Disposition", "attachment;filename=" + new String(fname.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8) + ".xls");
			response.setContentType("application/msexcel");//定义输出类型
			InputStream inputStream = this.getClass().getResourceAsStream("/exceldemo/weilfarExpendExport.xlsx");
			ExcelWriter excelWriter = EasyExcel.write(os).withTemplate(inputStream).build();
			FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
			WriteSheet writeSheet = EasyExcel.writerSheet(0).build();
			baseWelfareExpendVO.setTitle("职工福利费支出明细表(" + baseWelfareExpendVO.getFillingYear() + "年度)");
			if(baseWelfareExpendVO.getFillingDate() != null){
				baseWelfareExpendVO.setFillingDateStr(DateUtil.format(baseWelfareExpendVO.getFillingDate(), DateUtil.PATTERN_DATE));
			}
			excelWriter.fill(baseWelfareExpendVO, writeSheet);

			if (CollectionUtil.isNotEmpty(baseWelfareExpendVO.getWelfareExpendVOS())){
				List<WelfareExpendVO> welfareExpendVOS = baseWelfareExpendVO.getWelfareExpendVOS();
				for (int i = 0; i < welfareExpendVOS.size(); i++){
					WelfareExpendVO welfareExpendVO = welfareExpendVOS.get(i);
					if (i != welfareExpendVOS.size() - 1){
						welfareExpendVO.setIndex(i + 1);
					}

				}
				excelWriter.fill(new FillWrapper("list", baseWelfareExpendVO.getWelfareExpendVOS()), fillConfig, writeSheet);
			}
			excelWriter.finish();

		} catch (Exception e) {
			log.error(ExceptionUtils.getFullStackTrace(e));
		}
	}

	@Override
	public List<PageData> findWelfareListByDateCreate(PropertyTime propertyTime){
		List<PageData> listByDateRange = new ArrayList<>();
		try {
			PageData pageData = new PageData();
			pageData.put("startTime",propertyTime.getStartTime());
			pageData.put("endTime",propertyTime.getEndTime());
			List<PageData> pageDataList = welfareExpendMapper.welfareByCreat(pageData);
			HashMap<String, PageData> map = pdlistToMap(pageDataList);
			listByDateRange = mapAddPdlist(map, listByDateRange);
		} catch (Exception e) {
			log.error(ExceptionUtils.getFullStackTrace(e));
		}
		return listByDateRange;
	}


	public  HashMap<String, PageData> pdlistToMap(List<PageData> pageDataList){
		HashMap<String, PageData> map = new HashMap<>();
		for (PageData vo:pageDataList){
			String id = vo.getString("id");
			String fillingUnitId = vo.getString("fillingUnitId");
			String fillingMonth = vo.getString("fillingMonth");
			String key = id +"\t"+fillingUnitId+"\t"+fillingMonth;
			PageData pd1 = map.get(key);
			String welfareCategoryId = vo.getString("welfareCategoryId");
			String grantAmount = vo.getString("grantAmount");
			if (pd1 == null){
				PageData pd2 = new PageData();
				pd2.put(welfareCategoryId,grantAmount);
				map.put(key,pd2);
			}else {
				pd1.put(welfareCategoryId,grantAmount);
				map.put(key,pd1);
			}
		}
		return  map;
	}

	public List<PageData> mapAddPdlist(HashMap<String, PageData> map,List<PageData> list){
		for (String keyid : map.keySet()){
			PageData pd3 = new PageData();
			String[] split = keyid.split("\t");
			String id = split[0];
			String fillingUnitId = split[1];
			String fillingMonth = split[2];
			PageData pageData1 = map.get(keyid);
			for (Object pdid :pageData1.keySet()){
				pd3.put(pdid,pageData1.getString(pdid));
			}
			pd3.put("id",id);
			pd3.put("fillingUnitId",fillingUnitId);
			if(StringUtil.isNotBlank(fillingUnitId)) {
				PageData org = orgzationService.getCompanyNameById(fillingUnitId);
				if (org != null) {
					pd3.put("fillingUnitName",org.getString("name"));
				}
			}
			pd3.put("fillingMonth",fillingMonth);
			list.add(pd3);
		}
		return list;
	}


}
